﻿using WCS.Entity;
using WCS.WebRequest;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using WCS.Controls.RunLog;
using WCS.Helpers;
using WCS.Utils;
using Sunny.UI;

namespace WcsTask.DevCommTaks
{
    /// <summary>
    /// 堆垛机任务处理实体
    /// </summary>
    public class StackerTask
    {
        private StackerTask() { }

        private static readonly StackerTask stackerTask = new StackerTask();

        public static StackerTask _stackerTask
        {
            get
            {
                return stackerTask;
            }
        }

        /// <summary>
        /// 数据库对象
        /// </summary>
        static SqlSugarDapper _SqlSugarDapper = SqlSugarDapper.GetDbContext();

        /// <summary>
        /// 堆垛机设备
        /// </summary>
        static List<WcsDevStation> _stackerDev = _SqlSugarDapper.DB.Queryable<WcsDevStation>()
            .Where(w => SqlFunc.Subqueryable<WcsDevPlc>().Where(p => p.Dev_Code == w.DevCode && p.Dev_Type == Dev_Type.Stacker.ToString()).Any()).ToList();

        /// <summary>
        /// 入库数量
        /// </summary>
        int _inCount = Convert.ToInt32(ConfigurationManager.AppSettings["inCount"]);

        /// <summary>
        /// 出库数量
        /// </summary>
        int _outCount = Convert.ToInt32(ConfigurationManager.AppSettings["outCount"]);

        /// <summary>
        /// 出入库策略
        /// </summary>
        int _strategyType = Convert.ToInt32(ConfigurationManager.AppSettings["StrategyType"]);

        /// <summary>
        /// 仿真模式
        /// </summary>
        string _simulation = ConfigurationManager.AppSettings["simulation"];

        /// <summary>
        /// 上报WMS主任务当前状态
        /// </summary>
        string _ReportCurrentState = ConfigurationManager.AppSettings["ReportCurrentState"];

        /// <summary>
        /// 日志模块
        /// </summary>
        string _modular = "【堆垛机任务模块】";

        public List<WcsTaskStacker> wcsTaskStackerList
        {
            get
            {
                var list = _SqlSugarDapper.DB.SqlQueryable<WcsTaskStacker>("SELECT * from WCS_TASK_Stacker where TASK_CODE in (SELECT TASK_CODE from WCS_TASK_Main where TASK_STATE <> 102)").ToList();
                return list;
            }
        }

        /// <summary>
        /// 堆垛机任务处理
        /// </summary>
        public void StackerProcessTask()
        {
            while (true)
            {
                try
                {
                    foreach (var item in _stackerDev)
                    {
                        //找出当前堆垛机关联的待下发任务
                        var StackerTaskList = wcsTaskStackerList.FindAll(t => t.Task_State == (int)Task_State.等待执行 && t.Perform == item.Station_Plc_No);

                        //循环任务
                        foreach (var stackerTask in StackerTaskList)
                        {
                            WcsTaskStacker sednWcsTaskStacker = stackerTask;
                            if (stackerTask.Task_Type != "move")
                            {
                                //上一次执行任务的类型
                                var station = _SqlSugarDapper.DB.Queryable<WcsDevStation>().Where(w => w.Station_Plc_No == stackerTask.Perform).First();

                                // 一出一入策略
                                if (_strategyType == (int)StrategyType.一出一入)
                                {
                                    /*
                                        首先获取堆垛机上一次执行的任务类型
                                        是入库  就寻找出库任务发送  4
                                        是出库  就寻找入库任务发送  5
                                        */
                                    if (stackerTask.Perform == "9001")
                                    {
                                        //上一条是入库任务
                                        if (station.LastTaskType == "in")
                                        {
                                            //这次就查找出库任务执行
                                            sednWcsTaskStacker = StackerTaskList.Find(w => w.Task_Type == "out" && w.Perform == stackerTask.Perform);

                                            //如果出库任务已到达指定数量
                                            if (station.CurrentOutCount >= _outCount)
                                            {
                                                //就执行入库任务
                                                sednWcsTaskStacker = StackerTaskList.Find(w => w.Task_Type == "in" && w.Perform == stackerTask.Perform);
                                            }
                                        }
                                        //上一条是出库任务
                                        if (station.LastTaskType == "out")
                                        {
                                            //这次就查找入库任务执行
                                            sednWcsTaskStacker = StackerTaskList.Find(w => w.Task_Type == "in" && w.Perform == stackerTask.Perform);

                                            //如果入库任务已到达指定数量
                                            if (station.CurrentInCount >= _inCount)
                                            {
                                                //就执行出库任务
                                                sednWcsTaskStacker = StackerTaskList.Find(w => w.Task_Type == "out" && w.Perform == stackerTask.Perform);
                                            }
                                        }
                                    }
                                }
                                else if (_strategyType == (int)StrategyType.连续出入)
                                {
                                    //连续出入策略
                                    //如果出库任务未到达指定数量
                                    if (station.CurrentOutCount < _outCount)
                                    {
                                        //就执行出库任务
                                        sednWcsTaskStacker = StackerTaskList.Find(w => w.Task_Type == "out" && w.Perform == stackerTask.Perform);
                                    }
                                    //如果入库任务已到达指定数量
                                    if (station.CurrentInCount < _inCount)
                                    {
                                        //就执行出库任务
                                        sednWcsTaskStacker = StackerTaskList.Find(w => w.Task_Type == "in" && w.Perform == stackerTask.Perform);
                                    }
                                }
                                else
                                {
                                    RunLog.runLog.Warning($"出入库策略配置有误，请检查配置");
                                    return;
                                }

                                if (sednWcsTaskStacker == null)
                                {
                                    sednWcsTaskStacker = StackerTaskList.Find(w => w.Perform == stackerTask.Perform);
                                }

                                if (stackerTask.Perform == "9002" && _simulation == "0")
                                {
                                    //托盘库堆垛机执行出库任务后 下一个只能执行入库任务
                                    if (station.LastTaskType == "out" && stackerTask.Task_Type != "move")
                                    {
                                        sednWcsTaskStacker = StackerTaskList.Find(w => w.Task_Type == "in" && w.Perform == stackerTask.Perform);

                                        if (sednWcsTaskStacker == null)
                                        {
                                            if (!stackerTask.TaskTips.Contains("执行出库任务后 下一个只能执行入库任务"))
                                            {
                                                //更新任务提示
                                                _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                                                     .SetColumns(w => w.TaskTips == $"【堆垛机 {stackerTask.Perform}】执行出库任务后 下一个只能执行入库任务")
                                                     .Where(w => w.Sub_TaskCode == stackerTask.Sub_TaskCode).ExecuteCommand();

                                                RunLog.runLog.Warning($"【堆垛机 9002】执行出库任务后 下一个只能执行入库任务");
                                            }
                                            break;
                                        }
                                    }
                                }
                            }

                            //下发堆垛机任务
                            if (!StackerTaskSend(stackerTask))
                            {
                                //下发失败 退出当前堆垛机的任务循环  
                                break;
                            }
                        }
                    }

                    foreach (var stackerTaskList in wcsTaskStackerList)
                    {
                        if (stackerTaskList.Task_State == (int)Task_State.执行中)
                        {
                            StackerTaskFeedbackResult(stackerTaskList);
                        }
                        if (stackerTaskList.Task_State == (int)Task_State.任务完成)
                        {
                            //StackerTaskComplete(stackerTaskList);
                        }
                    }
                }
                catch (Exception ex)
                {
                    RunLog.runLog.Error($"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 主任务查分堆垛机任务
        /// </summary>
        /// <param name="wcsTaskMain"></param>
        /// <param name="NextRoute"></param>
        public bool MainTaskSplitStackerTask(WcsTaskMain wcsTaskMain, WcsRoute NextRoute)
        {
            try
            {
                //声明子任务实体
                WcsTaskStacker wcsTaskStacker = new WcsTaskStacker();

                wcsTaskStacker.Id = Guid.NewGuid().ToString();
                wcsTaskStacker.Task_Code = wcsTaskMain.Task_Code;//主任务号
                wcsTaskStacker.Sub_TaskCode = ProcessingTaskMain.GenerateRandomCode("sub");//子任务号 自己生成
                wcsTaskStacker.TrayBar_Code = wcsTaskMain.TrayBar_Code;//托盘号
                wcsTaskStacker.Start_Station = wcsTaskMain.Current_Station;//起始位置
                wcsTaskStacker.Task_Source = wcsTaskMain.Task_Source;//任务来源
                wcsTaskStacker.End_Station = NextRoute.Next_Station;//目标位置
                wcsTaskStacker.Current_Station = wcsTaskMain.Current_Station;//当前位置
                wcsTaskStacker.WMSEndStation = wcsTaskMain.End_Station;//当前位置
                wcsTaskStacker.Priority = wcsTaskMain.Priority;//优先级
                wcsTaskStacker.TaskTips = wcsTaskMain.TaskTips;//任务提示
                wcsTaskStacker.Task_State = (int)Task_State.等待执行;//任务状态
                wcsTaskStacker.Task_Type = wcsTaskMain.Task_Type;//任务类型
                wcsTaskStacker.CreateTime = DateTime.Now;//创建时间

                if (wcsTaskMain.Task_Type == "move")//移库任务单独处理
                {
                    wcsTaskStacker.Perform = wcsTaskMain.Start_Station;//执行设备 RVG和堆垛机的执行设备不是起始位置

                    wcsTaskStacker.StartWMSBinCode = wcsTaskMain.StartWMSBinCode;//WMS发送的库位号

                    wcsTaskStacker.EndWMSBinCode = wcsTaskMain.EndWMSBinCode;//WMS发送的库位号

                    RunLog.runLog.Debug($"{_modular}堆垛机移库任务拆分成功 【{wcsTaskStacker.Task_Code}】");
                }
                else
                {
                    if (wcsTaskMain.Task_Type == "in")
                    {
                        //入库 WMS会发送结束库位
                        wcsTaskStacker.Perform = NextRoute.Perform;//执行设备 RVG和堆垛机的执行设备不是起始位置

                        wcsTaskStacker.Start_Station = NextRoute.Start_Station;//起始库位用自己配置的
                        wcsTaskStacker.EndWMSBinCode = wcsTaskMain.EndWMSBinCode;//WMS发送的库位号
                    }
                    if (wcsTaskMain.Task_Type == "out")
                    {
                        //出库 WMS会发送起始库位
                        wcsTaskStacker.Perform = NextRoute.Perform;//执行设备 RVG和堆垛机的执行设备不是起始位置

                        wcsTaskStacker.StartWMSBinCode = wcsTaskMain.StartWMSBinCode;//WMS发送的库位号
                        wcsTaskStacker.End_Station = NextRoute.Next_Station;//结束库位用自己配置的
                    }
                }

                //添加任务
                _SqlSugarDapper.DB.Insertable(wcsTaskStacker).ExecuteCommand();

                return true;
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                return false;
            }
        }

        /// <summary>
        /// 十六进制字符串转十进制int
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public int String16ToInt10(string val)
        {
            string ss = "";
            for (int i = 0; i < val.Length / 2; i++)
            {
                ss += val.Substring(val.Length - 2 * (i + 1), 2);
            }

            var result = Convert.ToInt32(ss, 16);

            return result;
        }

        /// <summary>
        /// byte转Bit
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public string Read_Bit_Byte(byte[] val)
        {
            BitArray bitArray = new BitArray(val);
            string Text = "";

            for (int i = 0; i < bitArray.Count; i++)
            {
                Text += Convert.ToInt32(bitArray[i]) + " ";
            }

            return Text;
        }

        /// <summary>
        /// 堆垛机任务下发
        /// </summary>
        private bool StackerTaskSend(WcsTaskStacker wcsTaskStacker)
        {
            try
            {
                //根据站台号找到对应站台和所属PLC
                var plcDevStation = (StackerStation)PlcDev._plcDev.GetStationNo(wcsTaskStacker.Perform);

                //任务是否具备下发条件
                if (!TaskIssuable(wcsTaskStacker, plcDevStation))
                {
                    return false;
                }

                RunLog.runLog.Debug($"{_modular}准备下发堆垛机任务，任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");

                string[] startWmsBin = new string[3];
                //操作的起始库位
                if (wcsTaskStacker.StartWMSBinCode != "" && wcsTaskStacker.StartWMSBinCode != null)
                {
                    startWmsBin = wcsTaskStacker.StartWMSBinCode.Split('-');
                    startWmsBin[0] = startWmsBin[0].PadLeft(3, '0');
                    startWmsBin[1] = startWmsBin[1].PadLeft(3, '0');
                    startWmsBin[2] = startWmsBin[2].PadLeft(3, '0');
                }
                string[] EndWmsBin = new string[3];
                //操作的结束库位
                if (wcsTaskStacker.EndWMSBinCode != "" && wcsTaskStacker.EndWMSBinCode != null)
                {
                    EndWmsBin = wcsTaskStacker.EndWMSBinCode.Split('-');
                    EndWmsBin[0] = EndWmsBin[0].PadLeft(3, '0');
                    EndWmsBin[1] = EndWmsBin[1].PadLeft(3, '0');
                    EndWmsBin[2] = EndWmsBin[2].PadLeft(3, '0');
                }

                //发送的数据对象
                StackerWriteData stackerWriteData = new StackerWriteData();

                //创建堆垛机发送对象
                if (wcsTaskStacker.Task_Type == "in")//入库
                {
                    stackerWriteData.StartStation = wcsTaskStacker.Start_Station;
                    stackerWriteData.CommandType = (int)CommandType.入库;

                    stackerWriteData.EndRow = EndWmsBin[0];
                    stackerWriteData.EndColumn = EndWmsBin[1];
                    stackerWriteData.EndLayer = EndWmsBin[2];
                }
                else if (wcsTaskStacker.Task_Type == "out")//出库
                {
                    stackerWriteData.EndStation = wcsTaskStacker.End_Station;
                    stackerWriteData.CommandType = (int)CommandType.出库;

                    stackerWriteData.StartRow = startWmsBin[0];
                    stackerWriteData.StartColumn = startWmsBin[1];
                    stackerWriteData.StartLayer = startWmsBin[2];
                }
                else //移库
                {
                    stackerWriteData.CommandType = (int)CommandType.库位间移动;

                    stackerWriteData.StartRow = startWmsBin[0];
                    stackerWriteData.StartColumn = startWmsBin[1];
                    stackerWriteData.StartLayer = startWmsBin[2];

                    stackerWriteData.EndRow = EndWmsBin[0];
                    stackerWriteData.EndColumn = EndWmsBin[1];
                    stackerWriteData.EndLayer = EndWmsBin[2];
                }

                stackerWriteData.Task_Code = wcsTaskStacker.Sub_TaskCode;
                stackerWriteData.TrayBar_Code = wcsTaskStacker.TrayBar_Code;

                //首先创建一个数组
                byte[] writeBytes = new byte[30];

                var dsa = Encoding.UTF8.GetBytes("1");
                BitConverter.GetBytes(Convert.ToInt32(stackerWriteData.Task_Code)).CopyTo(writeBytes, 0);//任务号
                Encoding.UTF8.GetBytes(stackerWriteData.TrayBar_Code).CopyTo(writeBytes, 4);//托盘号
                BitConverter.GetBytes(Convert.ToInt16(stackerWriteData.CommandType)).CopyTo(writeBytes, 12);//指令类型
                BitConverter.GetBytes(Convert.ToInt16(stackerWriteData.StartRow)).CopyTo(writeBytes, 14);//起始排
                BitConverter.GetBytes(Convert.ToInt16(stackerWriteData.StartColumn)).CopyTo(writeBytes, 16);//起始列
                BitConverter.GetBytes(Convert.ToInt16(stackerWriteData.StartLayer)).CopyTo(writeBytes, 18);//起始层
                BitConverter.GetBytes(Convert.ToInt16(stackerWriteData.EndRow)).CopyTo(writeBytes, 20);//目标排
                BitConverter.GetBytes(Convert.ToInt16(stackerWriteData.EndColumn)).CopyTo(writeBytes, 22);//目标排
                BitConverter.GetBytes(Convert.ToInt16(stackerWriteData.EndLayer)).CopyTo(writeBytes, 24);//目标排
                

                BitArray bitArray = new BitArray(8);
                bitArray[0] = true;
                bitArray[1] = true;
                bitArray[2] = true;
                bitArray[3] = false;
                bitArray[4] = true;
                bitArray[5] = true;
                bitArray[6] = false;
                bitArray[7] = false;
                bitArray.CopyTo(writeBytes, 26);

                RunLog.runLog.Debug($@"{_modular} 给堆垛机【{plcDevStation.Station_Plc_No}】 
                            写入数据：任务类型:【{Enum.GetName(typeof(CommandType), stackerWriteData.CommandType)}】
                            任务号:【{stackerWriteData.Task_Code}】
                            托盘号:【{stackerWriteData.TrayBar_Code}】
                            起始站台【{stackerWriteData.StartStation}】
                            起始位置【{stackerWriteData.StartRow}】--【{stackerWriteData.StartColumn}】--【{stackerWriteData.StartLayer}】
                            目标站台【{stackerWriteData.EndStation}】
                            目标位置【{stackerWriteData.EndRow}】--【{stackerWriteData.EndColumn}】--【{stackerWriteData.EndLayer}】");

                //给设备下发任务任务

                //if (!PlcDev._plcDev.WriteData(plcDevStation,"", writeBytes))
                //{
                //    //更任务的任务提示
                //    _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                //         .SetColumns(w => w.TaskTips == $"任务下发失败")
                //         .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode).ExecuteCommand();

                //    RunLog.runLog.Warning($"{_modular} 下发任务失败 任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");
                //    return false;
                //}
                RunLog.runLog.Debug($"{_modular}【堆垛机】任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】给堆垛机【{plcDevStation.Station_Plc_No}】下发任务成功");

                //更任务的任务提示
                //更新子任务状态成执行中
                _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                     .SetColumns(w => new WcsTaskStacker()
                     {
                         TaskTips = $"下发成功，等待设备【】执行完成",
                         Task_State = (int)Task_State.执行中,
                         SendTime = DateTime.Now
                     })
                     .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode).ExecuteCommand();

                //更新主任务提示
                //更新主任务状态
                _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                     .SetColumns(w => w.Task_State == (int)Task_State.执行中)
                     .Where(w => w.Task_Code == wcsTaskStacker.Task_Code)
                     .ExecuteCommand();

                if (wcsTaskStacker.Task_Source == (int)Task_Source.WMS下发任务)
                {
                    var obj = new
                    {
                        taskCode = wcsTaskStacker.Task_Code,
                        trayCode = wcsTaskStacker.TrayBar_Code,
                        taskState = 55,
                        currentLocation = wcsTaskStacker.Current_Station
                    };

                    //上报WMS当前位置变更
                    HttpRequest.httpRequest.WebPostRequest(JsonConvert.SerializeObject(obj), _ReportCurrentState);
                }
                return true;
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                return false;
            }
        }

        /// <summary>
        /// 任务是否可下发
        /// </summary>
        /// <returns></returns>
        public bool TaskIssuable(WcsTaskStacker wcsTaskStacker, StackerStation plcDevStation)
        {
            try
            {
                if (plcDevStation == null)
                {
                    RunLog.runLog.Warning($"{_modular} 未找到【{wcsTaskStacker.Perform}】堆垛机");
                    return false;
                }

                //当前设备是否正在执行任务
                var exists = _SqlSugarDapper.DB.Queryable<WcsTaskStacker>().Where(w => w.Perform == wcsTaskStacker.Perform && w.Task_State == (int)Task_State.执行中).First();
                if (exists != null)
                {
                    if (!wcsTaskStacker.TaskTips.Contains("正在执行任务 无法下发新任务"))
                    {
                        //更新任务提示
                        _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                             .SetColumns(w => w.TaskTips == $"【堆垛机 {wcsTaskStacker.Perform}】正在执行任务 无法下发新任务")
                             .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode).ExecuteCommand();

                        RunLog.runLog.Warning($"{_modular} 【堆垛机 {wcsTaskStacker.Perform}】正在执行任务 无法下发新任务  任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");
                    }
                    return false;
                }

                //判断该设备是否报警
                if (plcDevStation.stackerState.WorkingMode == (int)WorkingMode.故障)
                {
                    if (!wcsTaskStacker.TaskTips.Contains("故障 无法下发任务"))
                    {
                        //更任务的任务提示
                        _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                                .SetColumns(w => w.TaskTips == $"堆垛机【{Enum.GetName(typeof(RearForkError), plcDevStation.stackerState.WorkingMode)}】故障 无法下发任务")
                                .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode).ExecuteCommand();

                        RunLog.runLog.Warning($@"{_modular}堆垛机【{plcDevStation.Station_Plc_No}】报警 {Enum.GetName(typeof(RearForkError), plcDevStation.stackerState.WorkingMode)}
                            故障 无法下发任务  任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");
                    }
                    return false;
                }

                //判断该设备状态是否可执行
                if (plcDevStation.stackerState.WorkingMode != (int)WorkingMode.在线)
                {
                    if (!wcsTaskStacker.TaskTips.Contains("不是空闲无法下发任务"))
                    {
                        //更任务的任务提示
                        _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                                .SetColumns(w => w.TaskTips == $"堆垛机【{plcDevStation.Station_Plc_No}】不是空闲无法下发任务")
                                .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode).ExecuteCommand();

                        RunLog.runLog.Warning($"堆垛机【{plcDevStation.Station_Plc_No}】不是空闲无法下发任务  任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");
                    }
                    return false;
                }

                //该设备是否启用
                var IsEnable = _SqlSugarDapper.DB.Queryable<WcsDevPlc>().Where(w => w.Dev_Code == plcDevStation.DevCode && w.Enable == "0").First();
                if (IsEnable != null)
                {
                    if (!wcsTaskStacker.TaskTips.Contains("已被禁用 无法下发任务"))
                    {
                        //更任务的任务提示
                        _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                             .SetColumns(w => w.TaskTips == $"【堆垛机】设备【{plcDevStation.DevCode}】已被禁用 无法下发任务")
                             .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode).ExecuteCommand();

                        RunLog.runLog.Warning($"{_modular} 【堆垛机】设备【{plcDevStation.DevCode}】已被禁用 无法下发任务  任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");
                    }
                    return false;
                }
                var existsCanCel = _SqlSugarDapper.DB.Queryable<WcsTaskMain>().Where(w => w.Task_Code == wcsTaskStacker.Task_Code && w.Task_State == (int)Task_State.任务取消).First();

                //是否取消该任务
                if (existsCanCel != null)
                {
                    RunLog.runLog.Warning($"{_modular} 【堆垛机】任务【{wcsTaskStacker.Task_Code}】已被取消 无法下发任务");
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                return false;
            }
        }

        /// <summary>
        /// 堆垛机任务反馈
        /// </summary>
        public void StackerTaskFeedbackResult(WcsTaskStacker wcsTaskStacker)
        {
            try
            {
                var stackerStation = PlcDev._plcDev.StackerStationList.Find(w => wcsTaskStacker.Task_Code == w.stackerState.TaskCode && wcsTaskStacker.TrayBar_Code == w.stackerState.TrayCode);

                if (stackerStation == null)
                {
                    return;
                }

                //根据任务的执行设备号找到对应的PLC信息
                //var plcDevStation = ConnectPlc.connectPlc.GetStationNo(wcsTaskStacker.Perform);
                //if (plcDevStation == null)
                //{
                //    RunLog.runLog.Warning($"{_modular} 未找到【{wcsTaskStacker.Perform}】堆垛机");
                //    return false;
                //}
                //如果任务的当前位置不等于站台信息的当前位置
                if (stackerStation.stackerState.TaskFeedback == (int)StackerTaskFeedback.取货完成)
                {
                    RunLog.runLog.Debug($"{_modular}【堆垛机】取货完成后 任务反馈数据成功 任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");
                    if (wcsTaskStacker.Task_Type == "in")
                    {
                        if (wcsTaskStacker.Task_Source == (int)Task_Source.WMS下发任务)
                        {
                            var obj = new
                            {
                                taskCode = wcsTaskStacker.Task_Code,
                                trayCode = wcsTaskStacker.TrayBar_Code,
                                taskState = 55,
                                currentLocation = ""
                            };

                            //上报WMS当前位置变更
                            HttpRequest.httpRequest.WebPostRequest(JsonConvert.SerializeObject(obj), _ReportCurrentState);
                        }
                    }

                    //更新主任务当前位置
                    _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                            .SetColumns(w => w.Current_Station == wcsTaskStacker.Perform)
                            .Where(w => w.Task_Code == wcsTaskStacker.Task_Code)
                            .ExecuteCommand();

                    //更新子任务当前位置
                    //更新输送线任务状态
                    _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                            .SetColumns(w => w.Current_Station == wcsTaskStacker.Perform)
                            .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode)
                            .ExecuteCommand();
                }
                if (stackerStation.stackerState.TaskFeedback == (int)StackerTaskFeedback.放货完成 || _simulation == "1")
                {
                    //记录堆垛机上一次执行任务的类型
                    if (wcsTaskStacker.Task_Type != "move")
                    {
                        _SqlSugarDapper.DB.Updateable<WcsDevStation>()
                            .SetColumns(w => w.LastTaskType == wcsTaskStacker.Task_Type)
                            .Where(w => w.Station_Plc_No == wcsTaskStacker.Perform)
                            .ExecuteCommand();
                    }

                    var count = _SqlSugarDapper.DB.Queryable<WcsDevStation>().Where(w => w.Station_Plc_No == wcsTaskStacker.Perform).First();

                    if (wcsTaskStacker.Task_Type == "out")
                    {
                        //找到当前堆垛机执行的任务数量 加一
                        count.CurrentOutCount++;

                        //增加出库数量
                        _SqlSugarDapper.DB.Updateable<WcsDevStation>()
                            .SetColumns(w => w.CurrentOutCount == count.CurrentOutCount)
                            .Where(w => w.Station_Plc_No == wcsTaskStacker.Perform)
                            .ExecuteCommand();

                        if (wcsTaskStacker.Task_Source == (int)Task_Source.WMS下发任务)
                        {
                            var obj = new
                            {
                                taskCode = wcsTaskStacker.Task_Code,
                                trayCode = wcsTaskStacker.TrayBar_Code,
                                taskState = 55,
                                currentLocation = wcsTaskStacker.End_Station
                            };

                            //上报WMS当前位置变更
                            HttpRequest.httpRequest.WebPostRequest(JsonConvert.SerializeObject(obj), _ReportCurrentState);
                        }
                    }
                    else if (wcsTaskStacker.Task_Type == "in")
                    {
                        //找到当前堆垛机执行的任务数量 加一
                        count.CurrentInCount++;

                        //增加入库数量
                        _SqlSugarDapper.DB.Updateable<WcsDevStation>()
                            .SetColumns(w => w.CurrentInCount == count.CurrentInCount)
                            .Where(w => w.Station_Plc_No == wcsTaskStacker.Perform)
                            .ExecuteCommand();
                    }

                    if ((count.CurrentInCount >= _inCount) && (count.CurrentOutCount >= _outCount))
                    {
                        ClearCount(wcsTaskStacker.Perform);
                    }

                    RunLog.runLog.Debug($"{_modular}【堆垛机】状态放货完成 准备处理任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");

                    //更新主任务当前位置
                    _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                            .SetColumns(w => w.Current_Station == wcsTaskStacker.End_Station)
                            .Where(w => w.Task_Code == wcsTaskStacker.Task_Code)
                            .ExecuteCommand();

                    //更任务的任务提示
                    //更新子任务当前位置
                    //更新子任务状态成任务完成
                    _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                             .SetColumns(w => new WcsTaskStacker()
                             {
                                 Current_Station = wcsTaskStacker.End_Station,
                                 Task_State = (int)Task_State.任务完成,
                                 CompleteTime = DateTime.Now
                             })
                            .Where(w => w.Sub_TaskCode == wcsTaskStacker.Sub_TaskCode)
                            .ExecuteCommand();

                    StackerTaskComplete(wcsTaskStacker);

                    RunLog.runLog.Debug($"{_modular}更新【堆垛机】任务状态【任务完成】成功 任务号:【{wcsTaskStacker.Task_Code}】堆垛机任务号:【{wcsTaskStacker.Sub_TaskCode}】");
                }
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
        }

        /// <summary>
        /// 清除出入库数量记录
        /// </summary>
        public void ClearCount(string Perform)
        {
            //增加入库数量
            _SqlSugarDapper.DB.Updateable<WcsDevStation>()
                .SetColumns(w => w.CurrentInCount == 0)
                .SetColumns(w => w.CurrentOutCount == 0)
                .Where(w => w.Station_Plc_No == Perform)
                .ExecuteCommand();
        }

        /// <summary>
        /// 堆垛机任务完成
        /// </summary>
        /// <param name="end_Station"></param>
        /// <param name="conveyTask"></param>
        private void StackerTaskComplete(WcsTaskStacker wcsTaskStacker)
        {
            try
            {
                if ((wcsTaskStacker.Task_Type == "in" || wcsTaskStacker.Task_Type == "move") || (wcsTaskStacker.End_Station == wcsTaskStacker.WMSEndStation))
                {
                    //更新主任务状态成上报完成 更新主任务提示
                    _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                          .SetColumns(w => w.Task_State == (int)Task_State.上报WMS任务完成)
                          .Where(w => w.Task_Code == wcsTaskStacker.Task_Code)
                          .ExecuteCommand();
                }
                else
                {
                    //更新主任务提示 把主任务更改为可拆分状态
                    _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                         .SetColumns(w => w.Split == 1)
                         .SetColumns(w => w.TaskTips == "准备拆分下一段任务")
                         .Where(w => w.Task_Code == wcsTaskStacker.Task_Code)
                         .ExecuteCommand();
                }

                DeleteStackerTask(wcsTaskStacker.Task_Code, "任务执行完成");
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
        }

        /// <summary>
        /// 删除堆垛机任务并加入历史记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="TaskCode"></param>
        public void DeleteStackerTask(string Task_Code, string TaskTips)
        {
            //更任务的任务提示
            _SqlSugarDapper.DB.Updateable<WcsTaskStacker>()
                .SetColumns(w => w.TaskTips == TaskTips)
                .Where(w => w.Task_Code == Task_Code)
                .ExecuteCommand();

            var wcsTaskStacker = _SqlSugarDapper.DB.Queryable<WcsTaskStacker>().Where(w => w.Task_Code == Task_Code).First();

            if (wcsTaskStacker != null)
            {
                WcsZBKTaskStacker wcsZBKTaskStacker = new WcsZBKTaskStacker();
                wcsZBKTaskStacker.MapperFrom(wcsTaskStacker);

                //添加历史记录
                _SqlSugarDapper.DB.Insertable<WcsZBKTaskStacker>(wcsZBKTaskStacker).ExecuteCommand();

                //删除子任务
                _SqlSugarDapper.DB.Deleteable<WcsTaskStacker>()
                   .Where(w => w.Task_Code == Task_Code)
                   .ExecuteCommand();
            }
        }
    }
}
